/*
 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 */

package demo.parallelcore;

import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;


/**
 * A demo shows how does Stream's subset works. This demo provides two methods
 * which is using substream method on Stream to get subset of the elements. Note
 * we can use substream on sorted stream to get top number elements, but we
 * can't guarantee the element order if stream is not sorted.
 *
 * @author hyan
 */

public class Subset extends DemoHelper {
   /**
    * Returns a List that contains numbers order which customer is from state, 
    * also execute action on every returned order element. The number must be a 
    * non-negative digit. <p>
    *
    * @param  number  integer how many orders are expected to be returned
    * @param  state   state that customer of order belong to 
    * @param  action  operation will be performed on every returned order
    *                 element
    * @return    a list contains top number customers that sorted by comp
    */
    public static List<Order>  firstNOrdersFromState(int number,
            String state, Consumer<Order> action){
        return customers.parallelStream().
                //only take customers from a particular state
                filter(c -> state.equals(c.getRegion())).
                //get orders of those customers
                flatMap(c -> c.getOrders().stream()).
                //get first number of orders
                substream(0, number).
                //apply the supplied action
                peek(action).
                //collect to a list
                collect(Collectors.toList());
    }
    
    /**
    * Returns a List that contains numbers customer sorted by comp, also execute
    * action on every returned customer element. The number must be a 
    * non-negative digit. <p>
    *
    * @param  number  integer how many customers are expected to be returned
    * @param  comp    Comparator to compare customer 
    * @param  action  operation will be performed on every returned customer
    *                 element
    * @return    a list contains top number customers that sorted by comp
    */
    public static List<Customer> topNCustomer(int number, 
            Comparator<Customer> comp, Consumer<Customer> action){
        //We keep result in topN, then we can test it
        return customers.parallelStream().
                //sort customers by comp
                sorted(comp).
                //get first number of orders
                substream(0, number).
                //apply the supplied action
                peek(action).
                //collect to a list
                collect(Collectors.toList());
    }
}
